package com.jjtm.common.core.utils.security;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * @author wangbaofeng
 */
public class Aes {
    /**
     * 密钥算法
     */
    private static final String KEY_ALGORITHM = "AES";

    /**
     * 密算法/工作模式/填充方式
     */
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    /**
     * 字符集
     */
    public static final String CHAR_SET = "UTF-8";

    /**
     * 加密消息
     *
     * @param message 明文消息
     * @param key     密钥，字符串长度必须为：16、24或32
     * @return 加密消息字节数组
     */
    public static byte[] encrypt(String message, String key){
        byte[] data = null;
        try {
            SecretKey secretKey = new SecretKeySpec(key.getBytes(CHAR_SET), KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            data = cipher.doFinal(message.getBytes(CHAR_SET));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return data;
    }

    /**
     * 加密消息
     *
     * @param message 明文消息
     * @param key     密钥，字符串长度必须为：16、24或32
     * @return 密文（BASE64编码）
     */
    public static String encryptToBase64(String message, String key){
        byte[] data = encrypt(message, key);
        return Base64.encodeBase64String(data);
    }

    /**
     * 解密
     *
     * @param message 待解密消息字节数组
     * @param key     密钥，字符串长度必须为：16、24或32
     * @return 解密符串
     */
    public static String decrypt(byte[] message, String key){
        String result = null;
        try {
            SecretKey secretKey = new SecretKeySpec(key.getBytes(CHAR_SET), KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] data = cipher.doFinal(message);
            result = new String(data);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    public static SecretKey initKeyForAes(String key) throws NoSuchAlgorithmException {
        if (null == key || key.length() == 0) {
            throw new NullPointerException("key not is null");
        }
        SecretKeySpec key2;
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        try {
            random.setSeed(key.getBytes(CHAR_SET));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try {
            KeyGenerator kGen = KeyGenerator.getInstance(KEY_ALGORITHM);
            kGen.init(128, random);
            SecretKey secretKey = kGen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            key2 = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
        } catch (NoSuchAlgorithmException ex) {
            throw new NoSuchAlgorithmException();
        }
        return key2;

    }
}
